﻿using System;
using System.Collections.Generic;
using System.Linq;
using Windows.UI.Xaml;
using com.IronOne.BoardPACWinAppBO.Agenda;
using com.IronOne.BoardPACWinAppBO.Auth;
using com.IronOne.BoardPACWinAppBO.Category;
using com.IronOne.BoardPACWinAppBO.General;
using com.IronOne.BoardPACWinAppBO.Meeting;
using com.IronOne.BoardPACWinAppBO.Paper;
using com.IronOne.BoardPACWinAppBO.Settings;
using com.IronOne.BoardPACWinAppDAO.DB;
using com.IronOne.BoardPACWinAppUtil.Util;

namespace com.IronOne.BoardPACWinAppDAO
{
    internal class EntityToModelMapper
    {
        internal static AppSettingModel MapAppSettingsToAppSettingModel(List<AppSettings> data)
        {
            try
            {
                if (data == null) return null;

                var asm = new AppSettingModel
                {
                    MinWebVersion = data.First(x => x.SettingName.Equals("MinWebVersion")).SettingValue,
                    ServerUrl = data.First(x => x.SettingName.Equals("ServerUrl")).SettingValue,
                    SyncSettings = Convert.ToBoolean(data.First(x => x.SettingName.Equals("SyncSettings")).SettingValue)
                };

                #region DateFormats | DateFormatSelected

                var dfList = data.First(x => x.SettingName.Equals("DateFormats")).SettingValue.Split('@');
                var dateFormats = dfList.Select(item => item.Split('#')).Select(kvPairs => new CustomKeyValuePair<string, string> {Key = kvPairs[0], Value = kvPairs[1]}).ToList();
                asm.DateFormats = dateFormats;

                var sdVals = data.First(x => x.SettingName.Equals("DateFormatSelected")).SettingValue.Split('#');
                asm.DateFormatSelected = asm.DateFormats.Find(x => x.Key.Equals(sdVals[0].Trim()));

                #endregion

                #region SyncFrequencies | SyncFrequencySelected

                var sfList = data.First(x => x.SettingName.Equals("SyncFrequencies")).SettingValue.Split('@');
                var syncFrequencies = sfList.Select(item => item.Split('#')).Select(kvPairs => new CustomKeyValuePair<string, string> {Key = kvPairs[0], Value = kvPairs[1]}).ToList();
                asm.SyncFrequencies = syncFrequencies;

                var sfVals =
                    data.First(x => x.SettingName.Equals("SyncFrequencySelected")).SettingValue.Split('#');
                asm.SyncFrequencySelected = asm.SyncFrequencies.Find(x => x.Key.Equals(sfVals[0].Trim()));

                #endregion

                return asm;
            }
            catch (Exception)
            {
                return null;
            }
        }

        internal static List<CategoryModel> MapMainCategoryToCategoryModel(List<MainCategory> data)
        {
            try
            {
                return data.Select(MapCategoryEntityToModel).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static CategoryModel MapCategoryEntityToModel(MainCategory item)
        {
            try
            {
                var cModel = new CategoryModel
                {
                    Actions = item.Actions,
                    CategoryId = item.CategoryID,
                    CategoryName = item.CategoryName,
                    CategoryOrder = item.CategoryOrder,
                    Info = item.Info,
                    LastUpdatedDateTime = item.LastUpdatedDateTime,
                    ShortName = item.ShortName
                };

                return cModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<SubCategoryModel> MapSubCategoryToSubCategoryModel(List<SubCategory> data)
        {
            try
            {
                var subCatModel = data.Select(MapSubCategoryEntityToModel).ToList();
                return subCatModel.OrderBy(x => x.SubCategoryOrder).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static SubCategoryModel MapSubCategoryEntityToModel(SubCategory item)
        {
            try
            {
                var scModel = new SubCategoryModel
                {
                    Actions = item.Actions,
                    CategoryId = item.CategoryId,
                    LastUpdatedDateTime = item.LastUpdatedDateTime,
                    Name = item.Name,
                    ShortName = item.ShortName,
                    Status = item.Status,
                    SubCategoryId = item.SubCategoryId,
                    SubCategoryOrder = item.SubCategoryOrder
                };

                return scModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<MeetingModel> MapMeetingEntityToMeetingModel(List<DB.Meeting> data)
        {
            try
            {
                return data.Select(MapMeetingEntityToMeetingModel).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static PaperModel MapPaperEntityToPaperModel(Paper item)
        {
            try
            {
                var paperModel = new PaperModel
                {
                    PaperId = item.PaperId,
                    DocName = item.DocName,
                    DocType = item.DocType,
                    HeadingId = item.HeadingID,
                    VersionId = item.VersionId,
                    VersionInfo = item.VersionInfo,
                    PaperRefNo = item.PaperRefNo,
                    PaperStatus = item.PaperStatus,
                    AgendaOrder = item.AgendaOrder,
                    CarryFwDinfo = item.CarryFWDinfo,
                    IsCarryFwDfromLastMeeting = item.IsCarryFWDfromLastMeeting,
                    IsPwdProtected = item.IsPwdProtected,
                    MemberApprovalComments = item.MemberApprovalComments,
                    MemberApprovalsString = item.MemberApprovalsString,
                    UserApprovalStatus = item.UserApprovalStatus,
                    NotificationDescription = item.NotificationDescription,
                    NotificationStatus = item.NotificationStatus,
                    RefId = item.RefId,
                    RefType = item.RefType,
                    ScrollingDirection = item.ScrollingDirection,
                    SubCategoryId = item.SubCategoryId,
                    CellColorB = item.CellColorB,
                    CellColorG = item.CellColorG,
                    CellColorR = item.CellColorR,
                    Description = item.Description,
                    DocCreatedDateTime = item.DocCreatedDateTime,
                    LastUpadatedDateTime = item.LastUpadatedDateTime,
                    LastUpadatedDateTimeDisplay = Utility.GetDateAsString(item.LastUpadatedDateTime),
                    DownloadStatus = item.DownloadStatus,
                    PresenterName = item.PresenterName,
                    StartTime = item.StartTime,
                    EndTime = item.EndTime,
                    PaperPresentedStatus = item.paperPresentedStatus,
                    PresenterEmail = item.PresenterEmail,
                    Info = item.Info,
                    IsAllowed = item.IsAllowed,
                    Actions = item.Actions
                };

                //MeetingId
                return paperModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static MeetingModel MapMeetingEntityToMeetingModel(DB.Meeting meetingEntity)
        {
            try
            {
                var mModel = new MeetingModel
                {
                    Actions = meetingEntity.Actions,
                    Address = meetingEntity.Address,
                    AttendenceReason = meetingEntity.AttendenceReason,
                    CategoryId = meetingEntity.CategoryId,
                    Date = meetingEntity.Date,
                    Description = meetingEntity.Description,
                    EndTime = meetingEntity.EndTime,
                    Info = meetingEntity.Info,
                    IsTentative = meetingEntity.IsTentative,
                    LastUpdatedDateTime = meetingEntity.LastUpdatedDateTime,
                    Latitude = meetingEntity.Latitude,
                    Longitude = meetingEntity.Longitude,
                    MeetingId = meetingEntity.MeetingId,
                    MeetingName = meetingEntity.MeetingName,
                    MeetingNote = meetingEntity.MeetingNote,
                    MeetingOrganizer = meetingEntity.MeetingOrganizer,
                    MeetingStatus = meetingEntity.MeetingStatus,
                    MeetingType = meetingEntity.MeetingType,
                    MemberAttendence = meetingEntity.MemberAttendence,
                    MemberIndividualAttendance = meetingEntity.MemberIndividualAttendance,
                    StartTime = meetingEntity.StartTime,
                    SubCategoryId = meetingEntity.SubCategoryId,
                    Venue = meetingEntity.Venue
                };

                return mModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<PaperModel> MapPaperEntityToPaperModel(List<Paper> data)
        {
            try
            {
                return data.Select(MapPaperEntityToPaperModel).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static MemberModel MapMemberToMemberModel(Member member)
        {
            try
            {
                var mModel = new MemberModel
                {
                    Address1 = member.Address1,
                    Address2 = member.Address2,
                    CompanyName = member.CompanyName,
                    ContactNo = member.ContactNo,
                    EmailId = member.EmailId,
                    FullName = member.FullName,
                    Info = member.Info,
                    IPadDisplayName = member.iPadDisplayName,
                    IsActive = member.isActive,
                    LastUpadatedDateTime = member.LastUpadatedDateTime,
                    MemberId = member.MemberId,
                    TimeStamp = member.TimeStamp
                };

                return mModel;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<LogDataModel> MapMemberToMemberModel(List<Log> logs)
        {
            try
            {
                return logs.Select(MapMemberToMemberModel).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static LogDataModel MapMemberToMemberModel(Log log)
        {
            try
            {
                var ldm = new LogDataModel
                {
                    LogId = log.LogId,
                    MemberId = log.MemberId,
                    Action = log.Action,
                    Data = log.Data,
                    MeetingId = log.MeetingID,
                    PaperId = log.PaperID,
                    UpdateId = log.UpdateID,
                    Info = log.Info,
                    Status = log.Status
                };

                return ldm;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<AgendaItem> MapHeadingToAgendaItem(List<Heading> headingList)
        {
            try
            {
                return headingList.Select(h => new AgendaItem
                {
                    Id = h.HeadingID,
                    PreviousId = h.PreviousHeadingId,
                    Order = h.AgendaOrder,
                    Name = h.Name,
                    HeadorPaper = 0,
                    IsHeading = Visibility.Visible,
                    IsPaper = Visibility.Collapsed,
                    IsAllowed = h.IsAllowed
                }).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static IEnumerable<AgendaItem> MapPaperToAgendaItem(List<Paper> paperList)
        {
            try
            {
                return paperList.Select(p => new AgendaItem
                {
                    Id = p.PaperId,
                    Name = p.DocName,
                    PreviousId = p.HeadingID,
                    Order = p.AgendaOrder,
                    HeadorPaper = 1,
                    VersionId = p.VersionId,
                    IsHeading = Visibility.Collapsed,
                    IsPaper = Visibility.Visible,
                    DocType = p.DocType,
                    PaperStatus = p.PaperStatus,
                    PaperRefNo = p.PaperRefNo,
                    NotificationStatus = p.NotificationStatus,
                    IsPaperAvailable = (p.DownloadStatus == 0),
                    DownloadStatus = (int) p.DownloadStatus,
                    //TODO: AnnotationVersion
                    //IsAnnotationReceived.
                    PaperDescription = p.Description,
                    IsAllowed = p.IsAllowed,
                    CellColorR = p.CellColorR,
                    CellColorG = p.CellColorG,
                    CellColorB = p.CellColorB,
                    DecisionStatus = p.UserApprovalStatus,
                    UserApprovalStatus = p.UserApprovalStatus,
                    PresenterName = p.PresenterName,
                    StartTime = String.IsNullOrEmpty(p.StartTime) ? "" : Utility.ConvertTime(p.StartTime),
                    EndTime = String.IsNullOrEmpty(p.EndTime) ? "" : Utility.ConvertTime(p.EndTime),
                    PresenterVisibility =
                        !string.IsNullOrEmpty(p.PresenterName) ? Visibility.Visible : Visibility.Collapsed,
                    ItemStatus = (p.paperPresentedStatus == 1) ? "Closed" : "Open",
                    PresenterCloseBtnVisibility =
                        (p.paperPresentedStatus == 0 && Global.IsBoardSecrartary)
                            ? Visibility.Visible
                            : Visibility.Collapsed

                    //TODO : To be implement later -> shared annotation, Annotate version
                }).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static UserModel MapCategoryEntityToModel(User user)
        {
            try
            {
                var um = new UserModel
                {
                    UserId = user.UserId,
                    IPadDisplayName = user.iPadDisplayName,
                    Email = user.Email,
                    UserFullName = user.UserFullName
                };
                return um;
            }
            catch (Exception)
            {
                throw;
            }
        }

        internal static List<PaperModel> MapAnnotationShareWithUserEntityToPaperModel(
            List<AnnotationShareWithUser> annotEntityList)
        {
            try
            {
                return annotEntityList.Select(item => new PaperModel
                {
                    PaperId = item.PaperId, VersionId = item.VersionId, AsAnnotationShareId = item.AnnotationShareId
                }).ToList();
            }
            catch (Exception)
            {
                throw;
            }
        }
    }
}